#pragma once

#include "Sock.hpp"
#include "log.hpp"
#include "protocol.hpp"

namespace client
{
    class calClient
    {
    public:
        calClient(const std::string &serverip, const uint16_t &serverport)
            : _serverip(serverip), _serverport(serverport), _sock(-1)
        {
        }

        void initClient()
        {
            _sock = Sock::Socket();
        }

        void start()
        {
            int n = Sock::Connect(_sock, _serverip, _serverport);
            if (n == -1)
            {
                logMessage(ERROR, "socket connect error");
            }
            else
            {
                std::string line;
                std::string inbuffer;
                while (true)
                {
                    std::cout << "mycal>>>";
                    std::getline(std::cin, line);
                    Request req = ParselLine(line);
                    std::string content;
                    req.serialize(&content);
                    std::string send_string = enLength(content);
                    std::cout << "sendstring:\n"
                              << send_string << std::endl;
                    send(_sock, send_string.c_str(), send_string.size(), 0);

                    std::string package, text;
                    // "content_len"\r\n"exitcode result"\r\n
                    if (!recvPackage(_sock, inbuffer, &package))
                        continue;
                    if (!deLength(package, &text))
                        continue;

                    // "exitcode result"
                    Response resp;
                    resp.deserialize(text);

                    std::cout << "exitcode: " << resp._exitcode << std::endl;
                    std::cout << "result: " << resp._result << std::endl;
                }
            }
        }

        Request ParselLine(const std::string &line)
        {
            int status = 0; // 0:操作符之前；1：碰到了操作符；2：操作符之后
            int i = 0;
            int len = line.size();
            std::string left, right;
            char op;
            while (i < len)
            {
                switch (status)
                {
                case 0:
                    if (!isdigit(line[i]))
                    {
                        op = line[i];
                        status = 1;
                    }
                    else
                        left.push_back(line[i++]);
                    break;
                case 1:
                    i++;
                    status = 2;
                    break;
                case 2:
                    right.push_back(line[i++]);
                    break;
                }
            }
            std::cout << std::stoi(left) << " " << std::stoi(right) << " " << op << std::endl;
            return Request(std::stoi(left), std::stoi(right), op);
        }

        ~calClient()
        {
            if (_sock > 0)
                close(_sock);
        }

    private:
        int _sock;
        std::string _serverip;
        uint16_t _serverport;
    };
}